package com.sxj.corejava.code07_面向对象.封装;

/**
 * @author 石小俊
 * @date 2025年01月06日
 */
public class Poker {

    private Card[] cards;

    public Card[] getCards() {
        return cards;
    }

    /**
     * 定义Poker的构造方法
     */
    public Poker() {
        // 为一副牌填充54张牌
        cards = new Card[54];
        // 定义每张牌可能出现的花色,忽略大小王
        String[] colors = {"方块", "梅花", "红桃", "黑桃"};
        // 定义每张牌可能出现的点数,忽略大小王
        String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

        // 定义cards数组的初始下标
        int index = 0;

        // 外层循环控制花色
        for (int i = 0; i < colors.length; i++) {
            // 内层循环控制点数
            for (int j = 0; j < nums.length; j++) {
                cards[index++] = new Card(colors[i], nums[j]);
            }
        }

        // 最后加入大小王
        cards[index++] = new Card("大", "王");
        cards[index++] = new Card("小", "王");
    }

    /**
     * 创建一个洗牌方法shuffle,将牌的顺序打乱后展示
     * 备注:创建一个新的数组,向该数组中填充元素,元素的来源为未洗牌前的数组
     */
    public void shuffle() {
        // 定义一个与原数组长度相同、类型相同的新数组
        Card[] cards = new Card[54];
        // 为新数组中的元素赋值,其值来源于原数组,且不能重复
        for (int i = 0; i < cards.length; i++) {
            // 随机获取未洗牌前的数组中的一张牌
            // 即:通过获取随机下标0-53所对应的一张牌
            int index = (int) (Math.random() * 54);
            // 根据指定下标获取到对应的扑克牌
            Card card = this.cards[index];

            // 如果card的值为null,说明已经被替换过,即:重复了
            while (card == null) {
                // 重新随机一张牌
                index = (int) (Math.random() * 54);
                card = this.cards[index];
            }

            // 当没有重复时
            // 当原数组中的某一个元素被使用了,则将该元素的值设置为null
            // 将扑克牌交给洗牌后的数组
            cards[i] = card;
            // 将未洗牌前的扑克牌设置为null
            this.cards[index] = null;
        }
        // 将洗牌后的值赋值给全局变量
        this.cards = cards;
    }

}
